from fastapi import FastAPI
from tortoise import Model, fields
from tortoise.contrib.fastapi import register_tortoise
from datetime import datetime
import uuid


# -------------------------- 基础模型（公共字段） --------------------------
class BaseModel(Model):
    """基础模型，包含公共字段"""
    id = fields.CharField(pk=True, max_length=32, default=lambda: uuid.uuid4().hex)
    create_time = fields.DatetimeField(default=datetime.now)
    update_time = fields.DatetimeField(auto_now=True)

    class Meta:
        abstract = True  # 抽象模型，不生成表


# -------------------------- 用户端相关表 --------------------------
class User(BaseModel):
    """用户表（用户端）：支撑登录、个人信息功能"""
    phone = fields.CharField(max_length=20, unique=True, description="手机号（登录账号）")
    password_hash = fields.CharField(max_length=128, null=True, description="密码哈希（可选，第三方登录可无）")
    nickname = fields.CharField(max_length=50, null=True, description="昵称")
    avatar = fields.CharField(max_length=255, null=True, description="头像URL")
    is_black = fields.BooleanField(default=False, description="是否黑名单")
    verify_status = fields.IntField(default=0, description="实名认证状态：0-未认证，1-审核中，2-已认证，3-审核驳回")



    class Meta:
        table = "user"  # 表名
        description = "用户端-用户基本信息"


class UserRealName(BaseModel):
    name = fields.CharField(max_length=50, description="真实姓名")
    id_card = fields.CharField(max_length=18, description="身份证号（18位）")
    sex = fields.CharField(max_length=10, description="性别")
    nation = fields.CharField(max_length=20, description="民族")
    birthday = fields.DateField(description="出生日期")
    address = fields.CharField(max_length=255, description="住址")
    id_card_front = fields.CharField(max_length=255, description="身份证正面照片URL")
    user = fields.OneToOneField("models.User", related_name="real_name", description="关联用户")

    class Meta:
        table = "user_real_name"
        description = "实名认证表"

class UserAddress(BaseModel):
    """用户地址表（用户端）：支撑地址管理功能"""
    user = fields.ForeignKeyField("models.User", related_name="addresses", description="关联用户")
    receiver = fields.CharField(max_length=50, description="收件人")
    phone = fields.CharField(max_length=20, description="收件人电话")
    province = fields.CharField(max_length=20, description="省份")
    city = fields.CharField(max_length=20, description="城市")
    detail = fields.CharField(max_length=255, description="详细地址")
    is_default = fields.BooleanField(default=False, description="是否默认地址")

    class Meta:
        table = "user_address"
        description = "用户端-用户常用地址"


class UserOrder(BaseModel):
    """用户订单表（用户端）：支撑订单管理功能"""
    order_no = fields.CharField(max_length=32, unique=True, description="订单编号（如ORD20251027XXX）")
    user = fields.ForeignKeyField("models.User", related_name="orders", description="关联用户")
    merchant = fields.ForeignKeyField("models.Merchant", related_name="orders", null=True, description="关联商家（可选，如平台订单无商家）")
    product_type = fields.CharField(max_length=20, description="产品类型：flight/hotel/ticket")
    product_id = fields.CharField(max_length=32, description="产品ID（如酒店ID/航班ID）")
    check_in_date = fields.DateField(description="入住日期")  # 新增入住日期字段
    check_out_date = fields.DateField(description="退房日期")  # 新增退房日期字段
    amount = fields.FloatField(description="订单金额")
    status = fields.IntField(default=0, description="状态：0待支付/1已支付/2已取消/3已完成")
    pay_time = fields.DatetimeField(null=True, description="支付时间")
    finish_time = fields.DatetimeField(null=True, description="完成时间")
    refund_status = fields.IntField(default=0, description="退款状态：0未退款/1申请中/2已退款")
    transaction_no = fields.CharField(max_length=64, null=True, description="支付宝交易号")

    class Meta:
        table = "user_order"
        description = "用户端-用户订单记录"


class UserFavorite(BaseModel):
    """用户收藏表（用户端）：支撑收藏功能"""
    user = fields.ForeignKeyField("models.User", related_name="favorites", description="关联用户")
    product_type = fields.CharField(max_length=20, description="产品类型：hotel/spot")
    product_id = fields.CharField(max_length=32, description="产品ID")

    class Meta:
        table = "user_favorite"
        unique_together = (("user", "product_type", "product_id"),)  # 防止重复收藏
        description = "用户端-用户收藏记录"


class UserCoupon(BaseModel):
    """用户优惠券表（用户端）：支撑优惠券领取/使用功能"""
    user = fields.ForeignKeyField("models.User", related_name="coupons", description="关联用户")
    coupon_id = fields.CharField(max_length=32, description="优惠券ID（关联MerchantCoupon/OperationActivity）")
    coupon_type = fields.CharField(max_length=20, description="类型：merchant（商家券）/platform（平台券）")
    is_used = fields.BooleanField(default=False, description="是否使用")
    use_time = fields.DatetimeField(null=True, description="使用时间")
    expire_time = fields.DatetimeField(description="过期时间")

    class Meta:
        table = "user_coupon"
        description = "用户端-用户持有的优惠券"


# -------------------------- 商家端相关表 --------------------------
class Merchant(BaseModel):
    """商家表（商家端）：支撑商家入驻/信息管理功能"""
    merchant_name = fields.CharField(max_length=100, description="商家名称")
    phone = fields.CharField(max_length=20, description="商家电话")
    contact_person = fields.CharField(max_length=50, null=True, description="联系人")
    address = fields.CharField(max_length=255, description="商家地址")
    license = fields.CharField(max_length=255, null=True, description="营业执照URL")
    status = fields.IntField(default=0, description="状态：0未审核/1正常/2禁用")

    class Meta:
        table = "merchant"
        description = "商家端-商家基本信息"


class Hotel(BaseModel):
    """房源表（商家端）：支撑房源管理功能"""
    merchant = fields.ForeignKeyField("models.Merchant", related_name="hotels", description="关联商家")
    hotel_name = fields.CharField(max_length=100, description="酒店名称")
    city = fields.CharField(max_length=20, description="所在城市")
    address = fields.CharField(max_length=255, description="详细地址")
    room_type = fields.CharField(max_length=50, description="房型（如：单人间/双人间/套房）")  # 新增房型字段
    price = fields.FloatField(description="单价（元/晚）")
    stock = fields.IntField(description="剩余库存")
    facilities = fields.JSONField(default=list, description="设施：['wifi', 'parking']")
    status = fields.IntField(default=1, description="状态：0下架/1上架")

    class Meta:
        table = "hotel"
        description = "商家端-酒店房源信息"


class HotelImage(BaseModel):
    """房源图片表（商家端）：支撑房源图片管理功能"""
    hotel = fields.ForeignKeyField("models.Hotel", related_name="images", description="关联房源")
    image_url = fields.CharField(max_length=255, description="图片URL")
    is_main = fields.BooleanField(default=False, description="是否主图")
    sort = fields.IntField(default=0, description="排序（数字越小越靠前）")

    class Meta:
        table = "hotel_image"
        description = "商家端-房源图片"


class MerchantCoupon(BaseModel):
    """商家优惠券表（商家端）：支撑商家营销功能"""
    merchant = fields.ForeignKeyField("models.Merchant", related_name="coupons", description="关联商家")
    title = fields.CharField(max_length=100, description="优惠券标题（如满200减50）")
    threshold = fields.FloatField(default=0, description="使用门槛（满X元可用）")
    discount = fields.FloatField(description="优惠金额")
    total = fields.IntField(description="总发行量")
    remain = fields.IntField(description="剩余数量")
    start_time = fields.DatetimeField(description="生效时间")
    end_time = fields.DatetimeField(description="过期时间")

    class Meta:
        table = "merchant_coupon"
        description = "商家端-商家发布的优惠券"


# -------------------------- 平台端相关表 --------------------------
class SysRole(BaseModel):
    """系统角色表（平台端）：支撑管理端权限控制"""
    role_name = fields.CharField(max_length=50, unique=True, description="角色名称（如超级管理员）")
    permissions = fields.JSONField(default=list, description="权限列表：['user:manage', 'order:view']")
    description = fields.CharField(max_length=255, null=True, description="角色描述")

    class Meta:
        table = "sys_role"
        description = "平台端-系统角色"



class SysUser(BaseModel):
    """系统用户表（平台端）：支撑管理端登录功能"""
    username = fields.CharField(max_length=50, unique=True, description="登录账号")
    password_hash = fields.CharField(max_length=128, description="密码哈希")
    role = fields.ForeignKeyField("models.SysRole", related_name="users", description="关联角色")
    name = fields.CharField(max_length=50, null=True, description="真实姓名")
    phone = fields.CharField(max_length=20, null=True, description="联系电话")
    status = fields.IntField(default=1, description="状态：0禁用/1正常")
    last_login_time = fields.DatetimeField(null=True, description="最后登录时间")

    class Meta:
        table = "sys_user"
        description = "平台端-管理端用户"


class OperationActivity(BaseModel):
    """运营活动表（平台端）：支撑平台营销功能"""
    title = fields.CharField(max_length=100, description="活动标题（如双11大促）")
    description = fields.TextField(null=True, description="活动描述")
    start_time = fields.DatetimeField(description="开始时间")
    end_time = fields.DatetimeField(description="结束时间")
    coupon_id = fields.CharField(max_length=32, null=True, description="关联平台优惠券ID")

    class Meta:
        table = "operation_activity"
        description = "平台端-运营活动"


class DataStat(BaseModel):
    """数据统计表（平台端）：支撑Dashboard数据展示"""
    stat_date = fields.DateField(description="统计日期")
    uv = fields.IntField(description="日活用户数")
    order_count = fields.IntField(description="当日订单数")
    gmv = fields.FloatField(description="当日GMV（元）")
    business_line = fields.CharField(max_length=20, description="业务线：flight/hotel/all")

    class Meta:
        table = "data_stat"
        unique_together = (("stat_date", "business_line"),)  # 同一日期+业务线唯一
        description = "平台端-数据统计"


class SysLog(BaseModel):
    """系统日志表（平台端）：支撑操作审计功能"""
    user = fields.ForeignKeyField("models.SysUser", related_name="logs", description="操作人")
    operation = fields.CharField(max_length=100, description="操作内容（如修改产品价格）")
    detail = fields.TextField(null=True, description="操作详情（JSON）")
    ip = fields.CharField(max_length=50, description="操作IP")

    class Meta:
        table = "sys_log"
        description = "平台端-系统操作日志"


